import ajax from "../../uni_modules/u-ajax/ajax.js"
import { BASE_URL,LOCAL,IMG_URL,DEFAULT_LOCATION,APP_NAME } from "../../env.js"
import { Ref, ref,computed, WritableComputedRef, } from "vue"
import { RequestResponse, Upload, Path } from "../interface/request"

export enum  requestMethod{
	post = "post",
	get = "get",
}


//字符串处理方法
export const strFn = {
	long(str:string,max:number):string{ //固定长度
		if(!str) return ''
		if(str.length>max){
			return str.slice(0,max)+'...'
		}else{
			return str
		}
	},
	hidePhone(str:string){ //手机号隐藏
		if(typeof str != 'string' || !str){
			return ''
		}else{
			let a = str.slice(0,3)
			let b = str.slice(7,11)
			return a+'****'+b
		}
	},
	img(value:string = '',flag:boolean=false):string{
		if(LOCAL && flag){
			return value
		}else{
			var header = value.slice(0, 4)
			let firstChar = value.slice(0,1)
			if(value == ''){
				return '/static/default/empty.jpg'
			}else{
				if (header === 'http' || firstChar !='/') {
					return value
				} else if (value) {
					return IMG_URL + value
				}
			}
		}
	},
	avatar(value:string = '') {
		var a = value.slice(0, 4)
		let b = value.slice(0,1)
		if(value == ''){
			return '/static/default/user.png'
		}else{
			if (a === 'http' || b!='/') {
				return value
			} else if (value) {
				return IMG_URL + value
			}
		}
	},
	wan(str:string):string | number{
		let num = +str
		let newNum = num/10000
		if(newNum >=1){
			return newNum+'万'
		}else{
			return num
		}
	},
	money(str:string | number){
		if(typeof str == 'number') str = str.toFixed(2)
		return String(str).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
	}
}

//检验类型
interface checkType {
	check:Function
	addRule:Function
}
export const useCheckType = ():checkType=>{
	let rules = {
		phone(str:string):Boolean{
			let RegExp = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
			return RegExp.test(str)
		},
		id(str:string):Boolean{
			let idRegexp = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
			//15位身份证
			let idRegexp2 = /^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$/
			return idRegexp.test(str) || idRegexp2.test(str)
		},
		email(str:string):Boolean{
			let RegExp = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
			return RegExp.test(str)
		},
		bank(str:string):Boolean{
			let RegExp = /^([1-9]{1})(\d{15}|\d{18})$/
			return RegExp.test(str)
		},
		video(str:string):Boolean{  //视频
			let videoRegex = /(.*)\.(mp4|rmvb|avi|ts)$/
			return videoRegex.test(str)
		}
	}
	return {
		check(str:string,key:string):string{
			if(!rules[key]) throw 'check规则不存在'
			return rules[key](str)
		},
		addRule(key:string,fn:Function):void{
			rules[key] = fn
		}
	}
}


//上传文件
export const upload = (filePath:string):Promise<Upload>=>{
	return new Promise((resolve)=>{
		uni.uploadFile({
			url:BASE_URL+'/api/common/upload',
			filePath,
			header:{'token':uni.getStorageSync('token')},
			name:'file',
			success(res) {
				let data = JSON.parse(res.data)
				uni.hideLoading()
				if(data.code == 401){
					uni.showModal({
						title:'登录提示',
						content:'请先登录',
						success(e) {
							if(e.confirm) uni.navigateTo({url:'/pages/public/login'})
						}
					})
				}
				resolve(data)
			},
			fail() {
				uni.showToast({
					title:'上传失败',
					icon:'error'
				})
				resolve(null)
			}
		})
	})
}


//预览图片
export const previewImg = (img:string | Array<string>,current:number = 0):void=>{
	//如果传的是一个字符串，将他改变为数组
	if(typeof img === 'string') img = img.split(',')
	//给所有没有域名的图片添加上域名
	let arr = img.map(item=> strFn.img(item))	
	uni.previewImage({
		urls:arr,
		current
	})	
}


//计算两点距离
interface distance {
	str:string
	value:number
}
export const getDistance = (lng1:number,lat1:number,lng2:number,lat2:number):distance=>{
	let PI = Math.PI 
	let R = 6378137
	let x:number,y:number,distance:number;
	let lngres:number = lng1 > lng2?lng1-lng2:lng2-lng1;
	x = (lngres) * PI * R * Math.cos(((lat1 + lat2) / 2) * PI / 180) / 180;
	y = (lat2 - lat1) * PI * R / 180;
	distance = Math.hypot(x, y);
	distance = Math.floor(distance)  
	return {
		str:distance<1000?distance+'m':(distance/1000).toFixed(2)+'km',
		value:distance
	}  
}


//提示消息
export const showToast = (title:string):void=>{
	uni.showToast({
		title,
		icon:'none',
		position:'center'
	})
}


///请求共享，避免同一请求多次执行

type tRequest = (method:string,url:string,data?:object,showToastFLag?:boolean)=>Promise<RequestResponse>
const useRequest = ():tRequest=>{
	//存放进行中的请求
	const pendingPromises = {};
	//请求方法、路径、参数、错误时是否弹窗提示
	const request = (method:string,url:string,data:object,showToastFLag:boolean=true):Promise<RequestResponse>=>{
		return new Promise((resolve,reject)=>{
			if(!method) throw 'method丢失'
			if(!url) throw 'url丢失'
			//判断是否存在请求，有就跳出
			let requestKey = JSON.stringify([method, url, data])
			if(pendingPromises[requestKey]) return 
			const fetchPromise = ajax({
				  method,
				  url,
				  data
			}).then((response:RequestResponse) =>{
				resolve(response)
			})
			.catch((err:any)=>{
				if(err.statusCode == 500){
					uni.showModal({
						title:'error',
						content:`
						请求路径:${err.config.url.replace(BASE_URL,'')};
						请求时间:${new Date()}
						`,
						confirmText:'复制信息',
						success(e) {
							if(e.confirm){
								uni.setClipboardData({
									data:`请求路径:${err.config.url};请求时间:${new Date()};token:${err.config.header.token};data:${JSON.stringify(err.config.data)}`
								})
							}
						}
					})
				}
				if(err.data.msg && showToastFLag) showToast(err.data.msg)
				reject(err)
			})
			.finally(() => { //请求完成将进行中的记录删除
				delete pendingPromises[requestKey];
			});
			pendingPromises[requestKey] = fetchPromise
		})
	}
	return request
}
export const tRequest = useRequest()


//验证当前app权限弹窗
const checkThisAppPromission = (key:string):Promise<boolean>=>{
	let config = {
		camera:{
			msg:`${APP_NAME}申请使用您的相册用于选择文件`
		},
		phone:{
			msg:`${APP_NAME}申请使用您电话用于拨号`
		}
	}
	return new Promise((resolve)=>{
		let promissionArr = uni.getStorageSync('promission')
		//如果没有权限列表，初始化为空数组
		if(!promissionArr) promissionArr = []
		if(!promissionArr.includes(key)){
			uni.showModal({
				title:'提示',
				content:config[key].msg,
				success(e) {
					if(e.confirm){
						resolve(true)
						promissionArr.push(key)
						uni.setStorageSync('promission',promissionArr)
					}
				}
			})
		}else{
			resolve(true)
		}
	})	
}


//简单分页
interface pagingObj {
	data:Ref<Array<any>> 
	getData:(obj?:object)=>void
	reload:(obj?:object)=>void
	getMore:(obj?:object)=>void
	page:number
	limit:number
	loading:Ref<boolean> 
	rowdata:Ref<any>
}
export const usePaging = (url:string,options?:any):pagingObj=>{
	let data = ref([])
	let page = 1
	let limit = 15
	let loading = ref(false)
	let method = 'post'
	let rowdata = ref({})
	let key = ''
	if(options){
		if(options.method) method = options.method
		if(options.limit) limit = options.limit
		if(options.key) key = options.key
	}
	
	
	if(!url) throw '请求路径丢失'
	
	//获取数据
	const getData = (obj:object = {},clear:boolean = false)=>{
		loading.value = true
		tRequest(method,url,{page,limit,...obj}).then((res:RequestResponse)=>{
			rowdata.value = res.data
			if(key){
				if(clear){
					data.value = res.data[key]
				}else{
					data.value.push(...res.data[key])
				}
			}else{
				if(clear){
					data.value = res.data
				}else{
					data.value.push(...res.data)
				}
			}
			uni.stopPullDownRefresh()
		}).finally(()=>{
			loading.value = false
		})
	}
	const getMore = (obj:object = {})=>{
		if(page*limit<=data.value.length){
			page++
			getData(obj)
		}
	}
	const reload = (obj:object ={})=>{
		page = 1
		data.value = []
		getData(obj,true)
	}
	
	return {
		data,
		getData,
		reload,
		getMore,
		page,
		limit,
		loading,
		rowdata
	}
}


//选择并上传图片
export const chooseAndUploadImg = ():Promise<Path>=>{
	return new Promise((resolve,reject)=>{	
		// #ifdef MP-WEIXIN
			uni.chooseMedia({
				count:1,
				mediaType:['image'],
				success(res){
					upload(res.tempFiles[0].tempFilePath).then((res:RequestResponse)=>{
						resolve(res.data.url)
					})
				},
				fail(err){
					reject(err)
				}
			})
		// #endif
		
		// #ifndef MP-WEIXIN
			checkThisAppPromission('camera').then(()=>{
				uni.chooseImage({
					count:1,
					success(e) {
						upload(e.tempFilePaths[0]).then((res:RequestResponse)=>{
							resolve(res.data.url)
						})
					}
				})
			})
		// #endif
			
	})
	
}

//判断是否是微信浏览器
export 	const isWechat = ():boolean => {
	return String(navigator.userAgent.toLowerCase().match(/MicroMessenger/i)) === "micromessenger";
}


//小程序获取定位
interface location {
	longitude:number | string
	latitude:number | string
}
export  const wxGetLocation = ():Promise<location>=>{
	return new Promise((resolve)=>{
		// #ifdef MP-WEIXIN
			uni.getSystemInfo({
				success(res) {
					let locationAuthorized  =  res.locationAuthorized  //定位服务是否允许微信授权
					let locationEnabled =  res.locationEnabled //定位服务是否开启
					if(!locationAuthorized  || !locationEnabled){
						//未授权定位服务
						showToast('未开启定位服务')
						resolve(DEFAULT_LOCATION)
					}else{
						uni.getFuzzyLocation({
							success(e) {resolve(e)},
							fail() {resolve(DEFAULT_LOCATION)}
						})
					}
				},
				fail(err) {
					let reg = /request:fail/
					showToast(reg.test(err.errMsg)?'无网络':'请求超时')
					resolve(DEFAULT_LOCATION)
				}
			})
		// #endif
	})
}

//选择图片 
export const chooseImg = (count:number):Promise<string | Array<string>>=>{
return new Promise((resolve)=>{
	// #ifdef APP
		//检查权限
		checkThisAppPromission('camera').then(()=>{
			uni.chooseImage({
				count,
				success(e) {
					resolve(e.tempFilePaths)
				}
			})
		})
	// #endif
	
	// #ifdef MP-WEIXIN
		uni.chooseMedia({
			mediaType:['image'],
			count,
			success(e){
				resolve(e.tempFiles.map(item=>item.tempFilePath))
			}
		})
	// #endif
})
}


//时间格式化
export const getTime = (time:string | number,mode?:number,):string=>{
	time = +time
	let date:any = new Date(time*1000)
	let today:any = new Date();
	let yesterday:any = new Date(today - 1000 * 60 * 60 * 24);
	let y:string | number = date.getFullYear()
	let m:string | number = date.getMonth()+1
	let d:string | number = date.getDate()
	let h:string | number = date.getHours()
	let mm:string | number = date.getMinutes()
	let s:string | number = date.getSeconds()
	m = String(m).padStart(2,'0')
	d = String(d).padStart(2,'0')
	h = String(h).padStart(2,'0')
	mm = String(mm).padStart(2,'0')
	s = String(s).padStart(2,'0')
	
	let isY = ()=>{
		return yesterday.getFullYear() == date.getFullYear() && yesterday.getMonth() == date.getMonth() && yesterday.getDate() == date.getDate()
	}
	let isT = ()=>{
		return today.getFullYear() == date.getFullYear() && today.getMonth() == date.getMonth() && today.getDate() == date.getDate()
	}
	
	switch(mode){
		case 1: return `${y}年${m}月${d}日`
		case 2: return `${y}-${m}-${d}`
		case 3:
			if(isY()){
				return `昨天${h}:${mm}`
			}else if(isT()){
				return `今天${h}:${mm}`
			}else{
				return `${y}-${m}-${d} ${h}:${mm}`
			}
		case 4:
			let count = today-date
			let day =  Math.floor(count/86400000)
			let mmm = Math.floor(count/60000)
			let hh = Math.floor(count/3600000)
			if(day>=1) return  day<7?`${day}天前`:`${y}年${m}月${d}日`
			if(hh>=1) return `${hh}小时前`
			if(mmm>=1) return `${mmm}分钟前`
			return '刚刚'
		case 5:
			return `${y}.${m}.${d} ${h}:${mm}:${s}`
		case 6: return `${y}-${m}`
		case 7: return `${m}-${d}`
		default: return `${y}-${m}-${d} ${h}:${mm}:${s}`
	}
}

//拆解路径
interface urlParams {
	path:string
	params:object
}
export const getParams = (link:string):urlParams=>{
	let path = link.split('?')[0]
	let params = link.split('?')[1]
	let arr = []
	let obj = {}
	if(params){
		 arr = params.split('&')
		 arr.forEach(item=>{
		 	obj[item.split('=')[0]] = item.split('=')[1]
		 })
	}
	return  {
		path,
		params:obj
	}
}

//拨打电话
export const phoneCall = (phoneNumber:string):void=>{
	phoneNumber = phoneNumber+''
	// #ifdef APP
		checkThisAppPromission('phone').then(()=>{
			uni.makePhoneCall({
				phoneNumber
			})
		})
	// #endif
	
	// #ifdef MP-WEIXIN
		uni.makePhoneCall({
			phoneNumber
		})
	// #endif
}


//登录验证
export const checkLogin = ()=>{
	if(uni.getStorageSync('token')){
		return true
	}else{
		uni.showModal({
			title:'提示',
			content:'请先登录',
			success(e) {
				if(e.confirm){
					uni.navigateTo({url:'/pages/public/login'})
				}
			}
		})
		return false
	}
}


//路由
export const routeFn = {
	back(msg?:string){//路由返回
		let stack = getCurrentPages() //当前路由栈
		if(msg) showToast(msg)
		setTimeout(()=>{
			if(stack.length<=1){
				uni.switchTab({url:'/pages/index/index'})
			}else{
				uni.navigateBack({
					fail: () => {
						uni.switchTab({url: '/pages/index/index'})
					}
				})
			}
		},msg?800:0)
	},
	to(path:string,needLogin:boolean=false){ //跳转
		let tabbar = ['/pages/index/index','/pages/worker/worker','/pages/mine/mine']
		if(!path) return
		if(needLogin && !checkLogin()) return
		let header = getParams(path).path.slice(0,4)
		if(header == 'http'){
			routeFn.adv(path)
		}else{
			uni[tabbar.includes(getParams(path).path)?'switchTab':'navigateTo']({url:path})
		}
	},
	adv(path:string){ //跳转广告页面
		if(path){
			let firstChar  = path.slice(0,1)
			if(firstChar == '/'){
				this.to(path)
			}else{
				// #ifdef APP
					plus.runtime.openWeb(path)
				// #endif
				// #ifdef MP-WEIXIN
					uni.navigateTo({
						url:'/pages/public/web?url='+path
					})
				// #endif
				// #ifdef H5
					let a = document.createElement('a')
					a.href = path
					a.target = '_blank'
					a.click()
					a.remove()
				// #endif
			}	
		}
	}
}


//微信小程序主动更新
export const wxchatMiniUpdate = ()=>{
	const updateManager = uni.getUpdateManager()
	updateManager.onCheckForUpdate(()=>{})
	updateManager.onUpdateReady(()=>{
		uni.showModal({
		    title: '更新提示',
		    content: '新版本已经准备好，是否重启应用？',
		    success(res) {
		      if (res.confirm) {
		        // 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
		        updateManager.applyUpdate()
		      }
		    }
		})
	})
}


//rpx转px
export const rpxTopx = (rpx:number):number=>{
  let deviceWidth = uni.getSystemInfoSync().windowWidth; //获取设备屏幕宽度
  let px = (deviceWidth / 750) * Number(rpx) 
  return Math.floor(px);
}

//处理vmodel绑定对象时
export const useVmodel = (props:object,propName:string,emit:Function):WritableComputedRef<any>=>{
	return computed({
		get(){
			return new Proxy(props[propName],{   //为每个属性绑定代理，当属性改变时意味着整个对象改变
				set(obj,name,val){
					emit('update:'+propName,{
						...obj,
						[name]:val
					})
					return true
				}
			})
		},
		set(val){
			emit('update:'+propName,val)
		}
	})
}


//打开地图
export const openMap = (latitude:number,longitude:number):void=>{
	latitude = +latitude
	longitude = +longitude
	uni.openLocation({
		latitude,
		longitude
	})
}


//计算划线价
export const getMarketPrice = (arr:Array<number>,total:number,market:number)=>{
	return arr.map(item=>{
		return  (item/total*market).toFixed(2)
	})
}

//获取已预约但未核销的订单
export const getLastOrder = (arr)=>{
	return arr.filter(item=> (!item.is_hx && item.yy_time))	
}



//小程序文件预览
const getFileType = (str:string)=>{
	return str.split('.').reverse()[0]
}
export const miniPre = (e)=>{
	let  fileType = getFileType(e)
	if(['wav','webm','mp4'].includes(fileType)){
		uni.navigateTo({
			url:'/pages/public/video?url='+e
		})
	}else if(fileType == 'pdf'){
		uni.showLoading({
			mask:true,
			title:'正在下载...'
		})
		uni.downloadFile({
			url:e,
			success(e) {
				uni.openDocument({
					filePath:e.tempFilePath,
				})
			},
			fail(e) {
				console.log(e,'fail')
			},
			complete() {
				uni.hideLoading()
			}
		})
	}else if(['jpg','png','jpeg','webp'].includes(fileType)){
		previewImg(e,0)
	} else{
		uni.showModal({
			title:'提示',
			content:'不支持在线预览该类型的文件,您可以选择下载到本地',
			confirmText:'复制链接',
			success(e) {
				if(e.confirm){
					uni.setClipboardData({
						data:e,
					})
				}
			}
		})
	}
}






